"""
@Author  : 康帅
@Time    : 2021/3/10 16:25
@Function: 账号登录异常登录时，发送短信或邮件提醒
"""

import time

# 引入抽象基类
from DesignMode.ListenMode.ListenBaseClass import Observable, Observer


class Account(Observable):
    """用户账户"""

    def __init__(self):
        """ 实例 """

        super().__init__()
        self.__latestIp = {}
        self.__latestRegion = {}

    def login(self, name, ip, times):
        region = self.__get_region(ip)
        if self.__is_long_distance(name, region):
            self.notify_ob_servers({"name": name, "ip": ip, "region": region, "times": times})
        self.__latestRegion[name] = region
        self.__latestIp[name] = ip

    def __get_region(self, ip):
        """ 由Ip地址获取地区信息 """

        ip_regions = {
            "101.47.17.9": "浙江省杭州市",
            "67.218.147.28": "河南省郑州市"
        }
        region = ip_regions.get(ip)
        return "" if region is None else region

    def __is_long_distance(self, name, region):
        """ 计算本次登录与最近几次登录的地区差距 """

        latestRegion = self.__latestRegion.get(name)
        return latestRegion is not None and latestRegion != region


class SmsSender(Observer):
    """ 短信发送器 """

    def update(self, observable, objects):
        print("[短信发送]" + objects["name"] +
              "您好！检测到您的账户可能登录异常，"
              "最近一次登录信息：\n" +
              "登录地区：" + objects["region"] +
              "登录ip：" + objects["ip"] +
              "登陆时间：" + time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(objects["times"])))


class MailSender(Observer):
    """ 邮件发送器 """

    def update(self, observable, objects):
        print("[邮件发送]" + objects["name"] +
              "您好！检测到您的账户可能登录异常，"
              "最近一次登录信息：\n" +
              "登录地区：" + objects["region"] +
              "登录ip：" + objects["ip"] +
              "登陆时间：" + time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(objects["times"])))


if __name__ == '__main__':
    account = Account()
    account.add_ob_server(SmsSender())
    account.add_ob_server(MailSender())
    account.login("Tony", "101.47.18.9", time.time())
    account.login("Tony", "67.218.147.28", time.time())
